#ifndef TCP_CONNECTION
#define TCP_CONNECTION

#include <ctime>
#include <iostream>
#include <string>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/asio.hpp>
#include <vector>
#include "Message.hpp"

class Tcp_Server;

using boost::asio::ip::tcp;


const  int TERRAINPACKETSIZE = 256;//Make your buffer larger than
const int c_MsgLengh		 = 128;

class Tcp_Connection  : public boost::enable_shared_from_this<Tcp_Connection>
{

public:

	friend class Tcp_Server;

	typedef boost::shared_ptr<Tcp_Connection> ConnectopnPointer;
	static ConnectopnPointer create(boost::asio::io_service& io_service)
	{
		return ConnectopnPointer(new Tcp_Connection(io_service));
	}

virtual	tcp::socket& socket()
	{
		return socket_;
	}

	virtual void start()
	{
		Receieve();
	}

protected:

	char buf[TERRAINPACKETSIZE];
	tcp::socket socket_;
	std::string Recv_Msg;
	std::string Send_Msg;

	Tcp_Connection(boost::asio::io_service& io_service): socket_(io_service)
	{

	}
virtual	bool Handle_Send( const boost::system::error_code& error, size_t bytes_transferred )
	{
		//std::cout<<"Sent "<<bytes_transferred<<" Bytes on Socket "<<std::endl;
		return false;
	}

virtual	bool Send( std::string strMsg )
	{
		if( socket_.is_open() )
		{
				if( strMsg.length() == c_MsgLengh )
				{

				boost::asio::async_write(socket_, boost::asio::buffer( strMsg.c_str() , strMsg.length() ),
												boost::bind( &Tcp_Connection::Handle_Send,
															shared_from_this(),
															boost::asio::placeholders::error,
															boost::asio::placeholders::bytes_transferred ) );
				}
				else
				{
					std::cout<<"Error, trying to send a message that has a length of "<<strMsg.length()<<std::endl;
				}
				return true;
		}
		else
		{
			std::cout<<"TCP_Connection::Send Error in socket"<<std::endl;
			return false;
		}
	};
virtual	void Recv_Handler(  const boost::system::error_code& error, // Result of operation.
							std::size_t bytes_transferred           // Number of bytes received.
						 )
	{
		std::cout<<"Warning: you are using the base class Handler !!!\n";
		if( !error )
		{
			std::cout<<"Received: "<<  buf <<std::endl;
			Receieve();
		}
		else
		{
			std::cerr<<"Error , closing connection \n";
			socket_.close();
		}
	};
	virtual void Receieve()
	{
		memset( buf, 0, TERRAINPACKETSIZE );

		boost::asio::async_read( socket_,	boost::asio::buffer( buf, c_MsgLengh ) ,
											boost::bind(  &Tcp_Connection::Recv_Handler ,
											shared_from_this(),
											boost::asio::placeholders::error,
											boost::asio::placeholders::bytes_transferred )
															);

		std::cout<<"TCP_Connection:: start receiving \n";
	}

};

#endif
